package com.ruoyi.business.component;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.common.config.RocketMqTopics;
import com.ruoyi.common.utils.FeishuUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * @author wqg
 * @description
 * @date 2022/5/21
 */
@Slf4j
@Service
public class RepaymentMqSendService {

    @Resource
    RocketMQTemplate rocketMQTemplate;

    /**
     * 同步发送还款mq信息
     *
     * @param type       发送区分类型，接收处理类型 查看BizConstants
     * @param jsonObject
     * @param custNo
     */
    public SendResult syncSendMqRepayMent(String type, JSONObject jsonObject, String custNo) {
        JSONObject paramJson = createMqJsonByType(type, jsonObject, custNo);
        log.info("custNo = {}，还款推送 MQ type = {}，data = {}，", custNo, type, paramJson.toJSONString());
        SendResult sendResult = rocketMQTemplate.syncSendOrderly(RocketMqTopics.getRepaymentTopic(), paramJson, custNo);
        log.info("custNo = {}，还款推送 MQ 结果 = {}，", custNo, sendResult.toString());
        if (!sendResult.getSendStatus().equals(SendStatus.SEND_OK)) {
            FeishuUtils.sendFeishuToMonit(type, "发送MQ异常 - 还款", custNo, sendResult.toString(), new Exception("mq异常"));
        }
        return sendResult;
    }

    /**
     * 构建paramJson给mq发送消息，包含类型
     *
     * @param type
     * @param jsonObject
     * @return
     */
    private JSONObject createMqJsonByType(String type, JSONObject jsonObject, String custNo) {
        JSONObject res = new JSONObject();
        res.put("type", type);
        res.put("custNo", custNo);
        res.put("msgObj", jsonObject);
        return res;
    }

    /**
     * 轮询3小的发送MQ
     *
     * @param jsonObject 还会被msgObj包裹
     * @param custNo
     */
    public SendResult syncSendMqRepayMentLunxun(JSONObject jsonObject, String custNo) {
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_LUNXUN, jsonObject, custNo);
    }

    /**
     * XXL-job定时查询还款结果进行冲账
     *
     * @param repaymentOrder
     * @param custNo
     */
    public SendResult syncSendMqRepayMentRefreshRepayResultJob(RepaymentOrder repaymentOrder, String custNo) {
        JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(repaymentOrder));
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_REFRESH_REPAY_RES, json, custNo);
    }

    /**
     * webHook还款 非 VA
     *
     * @param repaymentOrder
     * @param data
     */
    public SendResult webhookRepayment(RepaymentOrder repaymentOrder, JSONObject data) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentOrder", repaymentOrder);
        jsonParam.put("data", data);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_WEBHOOK, jsonParam, repaymentOrder.getCustNo());
    }

    /**
     * webHook还款 VA 非代扣
     *
     * @param reference
     * @return
     */
    public SendResult webhookVaRepayment(String reference, String custNo) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("reference", reference);
        jsonParam.put("custNo", custNo);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_WEBHOOK_VA, jsonParam, custNo);
    }

    /**
     * 余额代扣
     * @return
     */
    public SendResult cardBatchDebitRepayment(RepaymentOrder repaymentOrder,  JSONObject data) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentNo", repaymentOrder.getRepaymentNo());
        jsonParam.put("data", data);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_CARD_WITHHOLD, jsonParam, repaymentOrder.getCustNo());
    }




    /**
     * 主动还款
     *
     * @param repaymentOrder
     */
    public SendResult selfRepaymentMq(RepaymentOrder repaymentOrder) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentOrder", repaymentOrder);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_SELF_REPAYMENT, jsonParam, repaymentOrder.getCustNo());
    }

    /**
     * 催收还款
     *
     * @param repaymentOrder
     * @param creditAccount
     */
    public SendResult collectionRepaymentMq(RepaymentOrder repaymentOrder, CreditAccount creditAccount) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentOrder", repaymentOrder);
        jsonParam.put("creditAccount", creditAccount);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_COLLECTION, jsonParam, repaymentOrder.getCustNo());
    }

    /**
     * monnify
     *
     * @param jsonObject
     * @param custNo
     */
    public SendResult syncSendMqRepayMentMonnify(JSONObject jsonObject, String custNo) {
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_MONNIFY, jsonObject, custNo);
    }

    /**
     * monnify 轮询还款
     *
     * @param extMonnifyOrder
     */
    public SendResult monnifyLunxun(ExtMonnifyOrder extMonnifyOrder) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("extMonnifyOrder", extMonnifyOrder);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_MONNIFY_LUNXUN, jsonParam, extMonnifyOrder.getCustNo());
    }

    /**
     * 延期主动还款MQ
     *
     * @param repaymentOrder
     * @param creditAccount
     */
    public SendResult selfdeferRepaymentMq(RepaymentOrder repaymentOrder, CreditAccount creditAccount) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentOrder", repaymentOrder);
        jsonParam.put("creditAccount", creditAccount);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_SELF_REPAYMENT_DEFERRED, jsonParam, repaymentOrder.getCustNo());
    }

    /**
     * 延期主动还款—+钱包全额还款
     *
     * @param loanIou
     * @param productDeferredInfo
     * @param amtWallet
     * @param walletNo
     */
    public SendResult selfdeferWalletForAllPayRepaymentMq(LoanIou loanIou, ProductDeferredInfo productDeferredInfo, RepaymentOrder repaymentOrder, BigDecimal amtWallet, String walletNo) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("loanIou", loanIou);
        jsonParam.put("repaymentOrder", repaymentOrder);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_SELF_REPAYMENT_DEFERRED_WALLET_ALL, jsonParam, loanIou.getCustNo());
    }

    /**
     * 延期主动还款—+钱包部分还款
     *
     * @param repaymentOrder
     * @param creditAccount
     */
    public SendResult selfdeferWalletForBfenRepaymentMq(RepaymentOrder repaymentOrder, CreditAccount creditAccount) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentOrder", repaymentOrder);
        jsonParam.put("creditAccount", creditAccount);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_SELF_REPAYMENT_DEFERRED_WALLET_NOT_ALL, jsonParam, repaymentOrder.getCustNo());
    }

    /**
     * 主动还款钱包全额还款
     *
     * @param loanIou
     * @param repaymentOrder
     */
    public SendResult selfWalletForAllPayRepaymentMq(LoanIou loanIou, RepaymentOrder repaymentOrder) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("loanIou", loanIou);
        jsonParam.put("repaymentOrder", repaymentOrder);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_SELF_REPAYMENT_WALLET_ALL, jsonParam, loanIou.getCustNo());
    }

    /**
     * 非延期主动还款—+钱包部分还款
     *
     * @param repaymentOrder
     * @param creditAccountId
     */
    public SendResult selfWalletForBfenRepaymentMq(RepaymentOrder repaymentOrder, long creditAccountId) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentOrder", repaymentOrder);
        jsonParam.put("creditAccountId", creditAccountId);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_SELF_REPAYMENT_ALL_WALLET_NOT_ALL, jsonParam, repaymentOrder.getCustNo());
    }

    /**
     * 溢缴款冲账的MQ
     *
     * @param repaymentOrder
     */
    public SendResult overflowRepaymentMq(RepaymentOrder repaymentOrder, long creditAccountId) {
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("repaymentOrder", repaymentOrder);
        jsonParam.put("creditAccountId", creditAccountId);
        return syncSendMqRepayMent(BizConstants.ROCKMQ_REPAYMENT_TYPE_OVERFLOW_MQSERVICE, jsonParam, repaymentOrder.getCustNo());
    }
}
